require "rexml/document"

class ReviewTypeFactory
  def build(params)
    @params=params
    @review_type = ReviewType.new
    validate_params
    if(not @review_type.parsing_error?)
      parse_jucm_file
    end
    return @review_type
  end

  private

  RATING_CRITERION_REGEX=/(.*)\+review$/

  def validate_params
    if(@params[:review_type].nil?)
      return error "The .jucm file is required"
    end
    if(not jucm_file.original_filename=~ /(.*)\.jucm$/)
      return error "The file extension must be .jucm"
    end
  end

  def parse_jucm_file
    begin
      @review_type.name=jucm_file.original_filename
      @review_type.title=parse_review_type_title jucm_file.original_filename
      doc=REXML::Document.new(jucm_file.read)
      build_rating_criterions doc
    rescue Exception
      error "Unable to parse the .jucm file"  
    end
  end

  def build_rating_criterions(doc)
    build_overall_rating_criterion
    int_element_names=get_int_element_names_sorted(doc)
    int_element_names.each do |int_element_name|
      build_custom_rating_criterions int_element_name
    end
  end

  def get_int_element_names_sorted(doc)
    int_element_names=[]
    doc.elements.each("urn:URNspec/grlspec/intElements") do |int_element|
      int_element_names<<int_element.attributes["name"]
    end
    int_element_names.sort!

    return int_element_names
  end

  def build_overall_rating_criterion()
    build_rating_criterion(RatingCriterion::OVERALL_NAME)
  end

  def build_custom_rating_criterions(int_element_name)
    if( rating_criterion? int_element_name and 
        not RatingCriterion.overall_name? int_element_name)
      build_rating_criterion int_element_name
    end
  end

  def build_rating_criterion(name)
      rating_criterion=@review_type.rating_criterions.build(
        :name=>parse_rating_criterion_name(name)
      )
  end

  def rating_criterion?(element_name)
    element_name =~ RATING_CRITERION_REGEX
  end
  
  def parse_rating_criterion_name(element_name)
    element_name.sub(RATING_CRITERION_REGEX,'\1')
  end

  def parse_review_type_title(file_name)
    file_name.sub(/(.*)\.jucm$/,'\1')
  end

  def jucm_file
    @params[:review_type][:jucm_file]
  end

  def error(msg)
    @review_type.parsing_error=msg
  end
end
